﻿using System.Collections.Generic;
using System.Drawing;
using System.Net.NetworkInformation;

namespace GraphDrawing.Graph.Model
{
    /// <summary>
    /// Модель элемента.
    /// </summary>
    public class BlockModel
    {
        /// <summary>
        /// Список слотов текущего блока.
        /// </summary>
        readonly IList<SlotModel> slotList = new List<SlotModel>();

        /// <summary>
        /// Модель фигуры которой описывается блок.
        /// </summary>
        readonly IShape shapeModel;

        /// <summary>
        /// Координаты верхнего левого угла отрисовываемого элемента (в системе координат представления).
        /// </summary>
        public Point position;

        /// <summary>
        /// Флаг, равный true, если блок выбран в данный момент, иначе false.
        /// </summary>
        public bool IsSelected { get; set; }

        /// <summary>
        /// Модель фигуры блока.
        /// </summary>
        public object Shape
        {
            get { return shapeModel; }
        }

        /// <summary>
        /// Создаёт модель блока.
        /// </summary>
        /// <param name="shapeModel">Фигура, описывающая блок.</param>
        public BlockModel(IShape shapeModel)
        {
            this.shapeModel = shapeModel;
        }

        /// <summary>
        /// Возвращает слот с указанным индексом.
        /// </summary>
        /// <param name="index">Индекс слота.</param>
        public SlotModel GetSlot(int index)
        {
            return slotList[index];
        }

        /// <summary>
        /// Возвращает количество слотов.
        /// </summary>
        public int SlotCount
        {
            get { return slotList.Count; }
        }

        /// <summary>
        /// Перечисление слотов блока.
        /// </summary>
        public IEnumerable<SlotModel> Slots
        {
            get { return slotList; }
        }

        /// <summary>
        /// Добавляет несколько слотов в модель.
        /// </summary>
        public void SetSlots(ILayoutManager layoutManager, params SlotModel[] slotsModel)
        {
            slotList.Clear();
            for (var i = 0; i < slotsModel.Length; i++)
            {
                var slot = slotsModel[i];
                slotList.Add(slot);
                slot.Parent = this;
                slot.ParentDisposition = layoutManager.GetLocation(i);
            }
        }

        /// <summary>
        /// Возвращает прямоугольник описывающий область, в которую вписан блок, в глобальных координатах.
        /// </summary>
        public Rectangle GetBounds()
        {
            return new Rectangle(position, shapeModel.HitArea.Size);
        }

        /// <summary>
        /// Проверяет, попадает ли точка в границы блока.
        /// </summary>
        /// <param name="p">Глобальные координаты точки.</param>
        /// <returns>Возвращает true, если точка попадает в границы текущего блока, иначе false.</returns>
        public bool HitTest(Point p)
        {
            var translatedPoint = new Point(p.X - position.X, p.Y - position.Y);
            return shapeModel.HitArea.Contains(translatedPoint);
        }
    }
}
